package com.md.api.service.impl;

import com.aliyun.oss.model.StorageClass;
import com.md.api.common.utils.*;
import com.md.api.dao.*;
import com.md.api.entity.*;
import com.md.api.entity.dto.ComposeCommitDto;
import com.md.api.entity.dto.ComposeQueryDto;
import com.md.api.entity.enums.OssStorageClassLevel;
import com.md.api.entity.util.Page;
import com.md.api.service.PhotoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Author liujie
 * @ClassName PhotoServiceImpl
 **/

@Slf4j
@Service
public class PhotoServiceImpl implements PhotoService {
    @Resource
    VipPropertiesMapper vipMapper;
    @Resource
    UserVipMapper userVipMapper;
    @Resource
    TokenUtil tokenUtil;
    @Resource
    PhotoInfoMapper photoMapper;
    @Resource
    PictureInfoMapper pictureMapper;
    @Resource
    ShareRecordMapper shareRecordMapper;
    @Resource
    private UserMapper userMapper;
    @Autowired
    FileProperties properties;
    @Resource
    TbOrderVirtuallyMapper storageMapper;



    @Override
    public HttpResult photoPage(HttpServletRequest request, ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(PhotoInfo.class);
        String userId = tokenUtil.getUserId(request);

        List<PhotoInfo> list = photoMapper.getByUserId(userId,qto.getKeyword());
        page.setResult(list);
        return new HttpResult(page);
    }

    @Override
    public HttpResult picturePage(HttpServletRequest request, ComposeQueryDto qto) {
        String language = request.getHeader("language");
        PhotoInfo dbPhoto = photoMapper.getByPhotoId(qto.getPhotoId());
        if (null!=dbPhoto&&dbPhoto.getStatus()==-1){
            if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                return HttpResult.fail("The album is frozen. Please renew your membership or contact the administrator to unfreeze it");
            }
            return HttpResult.fail("相冊處於冷凍中，請續費會員或聯係管理員解凍！");
        }
        Page page = qto.getPage();
        page.initPagingData(PictureInfo.class);
        List<PictureInfo> list = pictureMapper.getByPhotoId(qto.getPhotoId(),qto.getKeyword(),null);
        page.setResult(list);
        return new HttpResult(page);
    }

    @Override
    public HttpResult newOne(HttpServletRequest request, PhotoInfo photoInfo) {
        String userId = tokenUtil.getUserId(request);

        photoInfo.setUserId(userId);
        String photoId = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        photoInfo.setPhotoId(photoId);

        //分配人脸库
        Integer i = StringUtils.intMode(photoId);
        String faceDbId = FaceRecognitionUtil.faceDbIds.get(i);
        photoInfo.setFaceDbId(faceDbId);
        photoMapper.save(photoInfo);
        return new HttpResult(photoId);
    }

    @Override
    public HttpResult savePicture(HttpServletRequest request, PictureInfo pictureInfo) {
        String language = request.getHeader("language");
        PhotoInfo dbPhoto = photoMapper.getByPhotoId(pictureInfo.getPhotoId());
        if (null!=dbPhoto&&dbPhoto.getStatus()==-1){
            if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                return HttpResult.fail("The album is frozen. Please renew your membership or contact the administrator to unfreeze it");
            }
            return HttpResult.fail("相冊處於冷凍中，請續費會員或聯係管理員解凍！");
        }
        if (null!=dbPhoto&&dbPhoto.getValidDate().getTime()<new Date().getTime()){
            if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                return HttpResult.fail("Album activity time has passed, operation not allowed");
            }
            return HttpResult.fail("相冊活動時間已過，不允許操作！");
        }
        if (null!=dbPhoto&&DateUtils.add(new Date(), Calendar.DATE,-30).getTime()>dbPhoto.getCreateTime().getTime()){
            if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                return HttpResult.fail("No operations allowed after 30 days of album creation");
            }
            return HttpResult.fail("相冊創建30天后不允許操作！");
        }
        try {
            String userId = tokenUtil.getUserId(request);
            UserInfo user = userMapper.getByUserId(userId);
            BigDecimal useStorage = new BigDecimal(user.getUseStorage());
            BigDecimal picSize = new BigDecimal(0);
            String[] pics = pictureInfo.getPictureUrl().split(",");
            for (String picPath:pics) {
                Long fileSize = AliOssUtil.getFileSize(picPath);
//                查询是否存在相同照片
                PictureInfo dbpic = pictureMapper.getByUrl(picPath);
                if (null != dbpic) {
                    dbpic.setSize(fileSize);
                    pictureMapper.updatePicture(dbpic);

                    //累积相片大小
                    BigDecimal num2 = new BigDecimal(fileSize);
                    picSize = picSize.add(num2).subtract(new BigDecimal(new Double(dbpic.getSize())));
                    //添加人脸样本及人脸数据
                    if (fileSize < 5 * 1024 * 1024 && (
                            picPath.endsWith("jpg") ||
                                    picPath.endsWith("jpeg") ||
                                    picPath.endsWith("png")
                    )) {
                        Boolean aBoolean = FaceRecognitionUtil.detectFace(picPath);
                        if (aBoolean) {
                            FaceRecognitionUtil.addFaceEntity(dbPhoto.getFaceDbId(), dbpic.getPictureId(), null);
                            String faceId = FaceRecognitionUtil.addFaceData(dbPhoto.getFaceDbId(), dbpic.getPictureId(), picPath);
                            if (StringUtils.isNotEmpty(faceId)) {
                                dbpic.setFaceId(faceId);
                                pictureMapper.updatePicture(dbpic);
                            }
                        }
                    }
                } else {
                    pictureInfo.setSize(fileSize);
                    pictureInfo.setUserId(userId);
                    pictureInfo.setPictureName(picPath.substring(picPath.lastIndexOf("/") + 1));
                    pictureInfo.setPictureUrl(picPath);
                    pictureInfo.setOssStorageClass(StorageClass.Standard.toString());
                    pictureInfo.setOssStorageClassLevel(OssStorageClassLevel.Standard.value());
                    String pictureId = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
                    pictureInfo.setPictureId(pictureId);

                    //累积相片大小
                    BigDecimal num2 = new BigDecimal(fileSize);
                    picSize = picSize.add(num2);

                    //添加人脸样本及人脸数据
                    if (fileSize < 5 * 1024 * 1024 && (
                            picPath.endsWith("jpg") ||
                                    picPath.endsWith("jpeg") ||
                                    picPath.endsWith("png")
                    )) {
                        Boolean aBoolean = FaceRecognitionUtil.detectFace(picPath);
                        if (aBoolean) {
                            FaceRecognitionUtil.addFaceEntity(dbPhoto.getFaceDbId(), pictureId, null);
                            String faceId = FaceRecognitionUtil.addFaceData(dbPhoto.getFaceDbId(), pictureId, picPath);
                            if (StringUtils.isNotEmpty(faceId)) {
                                pictureInfo.setFaceId(faceId);
                            }
                        }
                    }
                    pictureMapper.insert(pictureInfo);
                }
                //修改用户已用内存
                user.setUseStorage(useStorage.add(picSize).doubleValue());
                userMapper.updateUseStorage(user);
            }
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail(e.getMessage());
        }
        return HttpResult.OK;
    }


    @Override
    public HttpResult resetPhotoName(HttpServletRequest request, PhotoInfo photoInfo) {
        try {
            photoMapper.updatePhoto(photoInfo);
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("重命名失敗！");
        }
    }
    @Override
    public HttpResult setPhotoVideoUrl(HttpServletRequest request, PhotoInfo photoInfo) {
        try {
            photoMapper.updatePhoto(photoInfo);
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("設置影片地址失敗！");
        }
    }


    @Override
    public HttpResult setPhotoLogoUrl(HttpServletRequest request, PhotoInfo photoInfo) {
        try {

            String language = request.getHeader("language");
            String userId = tokenUtil.getUserId(request);
            UserVip currentVip = userVipMapper.getCurrentVip(userId);
            VipProperties vip = vipMapper.getByServiceCode(currentVip.getServiceCode());
            if (vip.getIsLogo()!=1){
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("Your membership privileges currently do not support custom logos. Please upgrade to a more advanced membership");
                }
                return HttpResult.fail("您的會員權限暫不支持自定義logo,請升級更高級會員！");
            }

            photoMapper.updatePhoto(photoInfo);
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("設置影片地址失敗！");
        }
    }

    @Override
    public HttpResult resetPictureName(HttpServletRequest request, PictureInfo pictureInfo) {
        try {
            pictureMapper.updatePicture(pictureInfo);
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("重命名失敗！");
        }
    }

    @Override
    public HttpResult transferPicture(HttpServletRequest request, ComposeCommitDto commitDto) {
        try {
            pictureMapper.transferPicture(commitDto.getPhotoId(),commitDto.getPictureIds());
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("轉移失敗！");
        }
    }


    @Override
    public HttpResult setPrivate(HttpServletRequest request, PhotoInfo photoInfo) {
        photoMapper.updatePhoto(photoInfo);
        return HttpResult.OK;
    }

    @Override
    public HttpResult deletePicture(HttpServletRequest request,PictureInfo picture) {
        try {
            PictureInfo dbPicture = pictureMapper.getByPictureId(picture.getPictureId());
            pictureMapper.deleteByPictureId(picture.getPictureId());
            //修改用户已用内存
            String userId = tokenUtil.getUserId(request);
            UserInfo user = userMapper.getByUserId(userId);
            BigDecimal num1 = new BigDecimal(user.getUseStorage());
            BigDecimal num2 = new BigDecimal(dbPicture.getSize());
            user.setUseStorage(num1.subtract(num2).doubleValue());
            userMapper.updateUseStorage(user);
            AliOssUtil.delShopImage(dbPicture.getPictureUrl());
            if (StringUtils.isNotEmpty(dbPicture.getFaceId())){
                PhotoInfo byPhotoId = photoMapper.getByPhotoId(dbPicture.getPhotoId());
                FaceRecognitionUtil.deleteFace(byPhotoId.getFaceDbId(),dbPicture.getFaceId());
                FaceRecognitionUtil.deleteFaceEntity(byPhotoId.getFaceDbId(),dbPicture.getPictureId());
            }
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("刪除失敗！");
        }
    }


    @Override
    public HttpResult refinePicture(HttpServletRequest request, PictureInfo picture) {
        try {
            String language = request.getHeader("language");
            PictureInfo dbPic = pictureMapper.getByPictureId(picture.getPictureId());
            PhotoInfo dbPhoto = photoMapper.getByPhotoId(dbPic.getPhotoId());
            String[] pathSegments = dbPic.getPictureUrl().split("/");
            String fileName = pathSegments[pathSegments.length - 1];
            MultipartFile file = FileUtils.fileUrlConvertToMultipartFile(fileName,picture.getPictureUrl());
            if (null==file){
                return HttpResult.fail("圖片獲取失敗！");
            }
            String userPath = tokenUtil.getUserId(request);
            UserInfo user = userMapper.getByUserId(userPath);
            Double totalEffectiveStorage = storageMapper.getTotalEffectiveStorage(userPath);
            if (null==totalEffectiveStorage) {
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("Insufficient storage space, please upgrade membership or purchase storage space");
                }
                return HttpResult.fail("存儲空間不足，請升級會員或購買存儲空間！");
            }
            Double total = Double.valueOf(String.valueOf(totalEffectiveStorage*1024*1024*1024));
            if (user.getUseStorage()>=total) {
                if(StringUtils.isNotEmpty(language)&&language.equals("en")){
                    return HttpResult.fail("Insufficient storage space, please upgrade membership or purchase storage space");
                }
                return HttpResult.fail("存儲空間不足，請升級會員或購買存儲空間！");
            }
            String path = AliOssUtil.upload(file, AliOssUtil.CUSTOM+userPath,fileName);
            long fileSize = file.getSize();
            System.out.println("file.getSize():"+fileSize);
            dbPic.setSize(fileSize);
//            dbPic.setPictureUrl(path);
            pictureMapper.updatePicture(dbPic);

            //修改用户已用内存
            BigDecimal num1 = new BigDecimal(user.getUseStorage());
            BigDecimal num2 = new BigDecimal(dbPic.getSize());
            BigDecimal num3 = new BigDecimal(fileSize);
            user.setUseStorage(num1.subtract(num2).add(num3).doubleValue());
            userMapper.updateUseStorage(user);

            //添加人脸样本及人脸数据
            Boolean aBoolean = FaceRecognitionUtil.detectFace(path);
            if (aBoolean){
                FaceRecognitionUtil.addFaceEntity(dbPhoto.getFaceDbId(),picture.getPictureId(),null);
                FaceRecognitionUtil.addFaceData(dbPhoto.getFaceDbId(),picture.getPictureId(),path);
            }

            return HttpResult.OK;
        } catch (Exception e) {
            log.error("精修更新失败", e);
            return HttpResult.fail(e.getMessage());
        }
    }

    @Override
    public HttpResult saveShare(HttpServletRequest request, ShareRecord shareRecord) {
        String userId = tokenUtil.getUserId(request);

        shareRecord.setShareUserId(userId);
        String shareId = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        shareRecord.setShareId(shareId);
        shareRecordMapper.saveShare(shareRecord);
        return null;
    }

    @Override
    public HttpResult setCoverImage(HttpServletRequest request, PictureInfo pictureInfo) {
        try {
            //先将所有的设置为不是封面
            pictureMapper.setCoverImage(pictureInfo);
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("設置封面失敗！");
        }
    }

    @Override
    public HttpResult setCherryPick(HttpServletRequest request, ComposeCommitDto commitDto) {
        try {
            pictureMapper.setIsCherryPick(commitDto.getPictureIds());
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("設置精選失敗！");
        }
    }


    @Override
    public HttpResult removeCoverImage(HttpServletRequest request, PictureInfo pictureInfo) {
        try {
            pictureInfo.setIsCoverImage(0);
            pictureMapper.updatePicture(pictureInfo);
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("取消封面失败！");
        }
    }

    @Override
    public HttpResult removeCherryPick(HttpServletRequest request, PictureInfo pictureInfo) {
        try {
            pictureInfo.setIsCherryPick(0);
            pictureMapper.updatePicture(pictureInfo);
            return HttpResult.OK;
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("取消精選失敗！");
        }
    }

    public static void main(String[] args) {
        Integer mode1 = "1b92be18cffc48ba8bf801e6a6e355c3".hashCode() % 10;
        if (mode1<0) mode1= mode1*-1;
        System.out.println(mode1);
        Integer mode2 = "28982a3638ac43cfb915b325f097ee8a".hashCode() % 10;
        if (mode2<0) mode2= mode2*-1;
        System.out.println(mode2);
        Integer mode3 = "417bf477fdcf482293e32899fed53c5c".hashCode() % 10;
        if (mode3<0) mode3= mode3*-1;
        System.out.println(mode3);
        Integer mode4 = "ca2ecbc951fe49e18e528f4b9b061759".hashCode() % 10;
        if (mode4<0) mode4= mode4*-1;
        System.out.println(mode4);
    }


}
